from application.entity.CommentEntity import CommentAdd, CommentOut, CommentReplyOut
from application.enumeration.StatusCodeEnum import StatusCodeEnum
from application.enumeration.ContentTypeEnum import ContentTypeEnum
from application.exception.BasicException import BasicException
from application.mapper.ReplyMapper import ReplyMapper
from application.mapper.NoteMapper import NoteMapper
from application.model.NoteModel import NoteModel
from application.mapper.CommentMapper import CommentMapper
from application.util.UserUtil import to_user_search_out
from application.model.CommentModel import CommentModel
from application.mapper.UserMapper import UserMapper
from application.model.UserModel import UserModel
from typing import Optional


async def add_comment(user_id: int, comment_add: CommentAdd) -> None:
    """
    添加评论（一级）
    :param user_id: 当前用户ID
    :param comment_add: 增加评论实体
    :return:
    """
    # 定义评论模型
    comment_model: CommentModel = await CommentModel(**comment_add.model_dump())
    comment_model.user_id = user_id
    # 添加一级评论
    if not await CommentMapper.insert(data=comment_model.to_dict()):
        raise BasicException(status_code=StatusCodeEnum.ERROR, message="评论失败，请稍后再试！")


async def delete_comment_by_id(comment_id: int, user_id: int, content_type: ContentTypeEnum) -> None:
    """
    根据评论ID删除评论
    :param comment_id: 评论ID
    :param user_id: 当前用户ID
    :param content_type: 文章类型
    :return:
    """
    # 获取评论模型
    comment_model: Optional[CommentModel] = await CommentMapper.get_data_by_field(id=comment_id,
                                                                                  content_type=content_type)
    if not comment_model:
        raise BasicException(status_code=StatusCodeEnum.NOT_FOUND_ERROR, message="评论不存在！")
    # 获取评论的目标文章模型
    target_model: Optional[NoteModel] = None
    if content_type == ContentTypeEnum.NOTE:
        target_model = await NoteMapper.get_data_by_field(id=comment_model.target_id)
    if not target_model:
        raise BasicException(status_code=StatusCodeEnum.NOT_FOUND_ERROR, message="文章不存在！")
    # 判断当前用户是否有权限删除该评论（评论用户ID为当前用户ID或者文章作者ID为当前用户ID）
    if comment_model.user_id != user_id or target_model.user_id != user_id:
        raise BasicException(status_code=StatusCodeEnum.AUTHORITY_ERROR, message="没有权限！")
    if not await CommentMapper.delete_by_field(id=comment_id):
        raise BasicException(status_code=StatusCodeEnum.ERROR, message="删除失败，请稍后再试！")


async def get_list(target_id: int, content_type: ContentTypeEnum,
                   page: int, page_size: int) -> list[Optional[CommentOut]]:
    """
    根据文章ID获取评论列表
    :param target_id: 目标ID
    :param content_type: 文章类型
    :param page: 当前页
    :param page_size: 每页条数
    :return:
    """
    result: list = []
    for comment_model in await CommentMapper.get_data_list(page=page, page_size=page_size, target_id=target_id,
                                                           content_type=content_type):
        # 构造评论输出实体
        comment_out: CommentOut = CommentOut(**comment_model.to_dict())
        # 设置用户信息
        user_model: Optional[UserModel] = await UserMapper.get_data_by_id(data_id=comment_model.user_id)
        # 如果该用户不存在，则跳过该评论
        if not user_model:
            continue
        comment_out.user_info = await to_user_search_out(user_model=user_model)
        # 设置回复列表，只显示5个
        for reply_model in await ReplyMapper.get_data_list(page=1, page_size=5, comment_id=comment_model.id):
            # 构造回复输出实体
            reply_out: CommentReplyOut = CommentReplyOut(**reply_model.to_dict())
            # 设置回复用户信息
            reply_user_model: Optional[UserModel] = await UserMapper.get_data_by_id(data_id=comment_model.user_id)
            # 如果该用户不存在，则跳过该回复
            if not reply_user_model:
                continue
            reply_out.user_info = await to_user_search_out(user_model=reply_user_model)
            comment_out.reply_list.append(reply_out)
        result.append(comment_out)
    return result
